﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Taxonomy;
using System.Collections;

namespace MMCP
{

    public class TermHierarchyDataComparer : IEqualityComparer<TermHierarchyData>
    {
        public bool Equals(TermHierarchyData x, TermHierarchyData y)
        {
            return string.Equals(x.HierarchyID, y.HierarchyID, StringComparison.InvariantCultureIgnoreCase);
        }

        public int GetHashCode(TermHierarchyData obj)
        {
            //return obj.GetHashCode();
            return obj.HierarchyID.GetHashCode();
        }
    }
    public class TermParentComparer : IEqualityComparer<TermHierarchyData>
    {
        public bool Equals(TermHierarchyData x, TermHierarchyData y)
        {
            return object.Equals(x.ParentNode, x.ParentNode);
        }

        public int GetHashCode(TermHierarchyData obj)
        {
            //return obj.GetHashCode();
            return obj.ParentNode.GetHashCode();
        }
    }
    public static class ManagedMetadataExtensions
    {
        public static IEnumerable<TermHierarchyData> GetAllTerms(this TaxonomySession session, string TermGroupName, string TermSetName, string delimiter)
        {
            TermStore termStore = session.DefaultKeywordsTermStore;
            Group group = termStore.Groups[TermGroupName];
            TermSet termSet = group.TermSets[TermSetName];

            return termSet.GetTermHierarchyData(termSet.Name, termSet.Id.ToString("N"));
        }

        public static string NormalizeTaxonomyPath(this string value)
        {
            return value.Replace(',', '.').Replace(';', '.');
        }

        public static TermHierarchyData GetDataForTerm(this Term term)
        {
            string Context = term.TermSet.Name;
            string ContextHierarchyID = term.TermSet.Id.ToString("N");
            return new TermHierarchyData()
            {
                HasChilds = term.TermsCount > 0,
                HierarchyID = term.Id.ToString("N"),
                DisplayName = term.Name,
                ParentNode = GetParentForTerm(term)
            };
        }
        public static TermHierarchyData GetParentForTerm(this Term term)
        {
            if (term.Parent != null)
                return term.Parent.GetDataForTerm();
            if (term.TermSet != null)
                return term.TermSet.GetData();

            return term.TermStore.GetData();
        }
        public static TermHierarchyData GetData(this TermSet termset)
        {
            return new TermHierarchyData()
            {
                 DisplayName = termset.Name,
                 HierarchyID = termset.Id.ToString("N"),
                 HasChilds = termset.Terms.Count > 0,
                 ParentNode = termset.TermStore.GetData()
            };
        }
        public static TermHierarchyData GetData(this TermStore termstore)
        {
            return new TermHierarchyData()
            {
                DisplayName = termstore.Name,
                HierarchyID = termstore.Id.ToString("N"),
                HasChilds = true,
                ParentNode = null
            };
        }


        public static IEnumerable<TermHierarchyData> GetTermHierarchyData(this TermSet termSet, string Context, string ContextHierarchyID)
        {
            var result = from term in termSet.GetAllTerms()
                         where term.IsAvailableForTagging
                         orderby term.GetPath()
                         let hid = term.TermSet.Name
                         select term.GetDataForTerm();

            //// if context is not empty add fake parent nodes
            //if (!string.IsNullOrEmpty(Context))
            //{
            //    List<TermHierarchyData> tmp = new List<TermHierarchyData>();
            //    tmp.Add(new TermHierarchyData()
            //        {
            //            HierarchyID = ContextHierarchyID,
            //            DisplayName = Context,
            //            Path = Context,
            //            HasChilds = true,
            //            IsRootNode = true,
            //            ParentNodeID = string.Empty
            //        });

            //    tmp.AddRange(result);
                
            //    result = tmp;
            //}

            return result.Distinct(new TermHierarchyDataComparer());
        }

        internal static IEnumerable<TermHierarchyData> GetRootTerms(this IEnumerable<TermHierarchyData> terms)
        {
            var parents = from term in terms
                          select term.ParentNode;
            return parents.Distinct(new TermHierarchyDataComparer()).OrderBy(n => n.DisplayName);

            //return (from path in terms
            //        where path.IsRootNode
            //        select path).Distinct(new TermHierarchyDataComparer()).OrderBy(n=>n.Path);
        }
        internal static IEnumerable<TermHierarchyData> FilterTerms(this IEnumerable<TermHierarchyData> terms, string ParentNodeId)
        {
            return (from path in terms
                    where string.Equals(path.ParentNode.HierarchyID, ParentNodeId, StringComparison.InvariantCultureIgnoreCase)
                    select path).Distinct(new TermHierarchyDataComparer()).OrderBy(n => n.DisplayName);
        }
    }
}
